package com.nowcoder.community.quartz;

import com.nowcoder.community.contant.Entity;
import com.nowcoder.community.entity.DiscussPost;
import com.nowcoder.community.service.DisccusPostService;
import com.nowcoder.community.service.ElasticsearchService;
import com.nowcoder.community.service.LikeService;
import com.nowcoder.community.utils.RedisKeyUtil;
import lombok.extern.slf4j.Slf4j;
import org.quartz.Job;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.BoundSetOperations;
import org.springframework.data.redis.core.RedisTemplate;

import java.time.LocalDate;
import java.time.Period;
import java.time.ZoneId;

@Slf4j
public class PostScoreRefreshJob implements Job {

    @Autowired
    private RedisTemplate redisTemplate;

    @Autowired
    private DisccusPostService disccusPostService;

    @Autowired
    private LikeService likeService;

    @Autowired
    private ElasticsearchService elasticsearchService;

    private final LocalDate epoch = LocalDate.of(2020, 1, 1);

    /**
     * 更新帖子分数
     * */
    @Override
    public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException {
        log.info("开始更新帖子分数");
       String redisKey = RedisKeyUtil.getPostScoreUpdateRedisKey();
        BoundSetOperations setOps = redisTemplate.boundSetOps(redisKey);
        while (setOps.size() > 0){
            int postId = (int) setOps.pop();
            DiscussPost post = disccusPostService.findDiscussPostById(postId);
            if (post == null){
                log.warn("找不到该帖子：" + postId);
            }else if (post.getStatus() == 2){
                log.info("帖子已被拉黑");
            }else {
                post.setScore(getPostScore(post));
                disccusPostService.updateScore(post.getId(),post.getScore());
                elasticsearchService.addDiscussPost(post);
            }
        }
    }

    /**
     * 帖子分数计算公式：log(精华分 75 + 评论数 * 10 + 点赞数 * 2) + (发布时间 - 牛客纪元) 天数
     * */
    private double getPostScore(DiscussPost post){
        long likes = likeService.countEntityLikes(Entity.DISCUSS_POST, post.getId());
        long weight = (post.getStatus() == 1 ? 75 : 0) + post.getCommentCount() * 2 + likes * 2;
        LocalDate createTime = post.getCreateTime().toInstant().atZone(ZoneId.systemDefault()).toLocalDate();
        return Math.log10(Math.max(weight, 0)) + (Period.between(epoch, createTime).getDays());
    }
}
